#ifndef __DSTH_PD_CODEC_H__
#define __DSTH_PD_CODEC_H__

#include <google/protobuf/message.h>

#include "Timestamp.h"
#include "Connection.h"

using google::protobuf::Message;

namespace dsth {

class PBCodec {
public:
    enum ErrorCode {
        kNoError = 0,
        kInvalidLength,
        kCheckSumError,
        kInvalidNameLen,
        kUnknownMessageType,
        kParseError,
    };
    typedef Acf::Delegate<void (Connection* conn, Message* msg, Timestamp time)> MessageHandler;
    typedef Acf::Delegate<void (Connection* conn, ChannelBuffer* buffer, Timestamp time)> ErrorMsgHandler;

    PBCodec(MessageHandler msg_handler, ErrorMsgHandler error_handler);
    void OnMessage(Connection* conn, ChannelBuffer* buffer, Timestamp time);
    void SendMessage(const Connection* conn, const Message* msg);

private:
    PBCodec(const PBCodec&);
    void operator=(const PBCodec&);

    Message* PBCodec::Parse(const char* data, int32_t len, ErrorCode* errorcode);
    Message* CreateMessage(const std::string& name);
    MessageHandler msg_handler_;
    ErrorMsgHandler error_handler_;

    const static int kHeaderLen = sizeof(int32_t);
    const static int kMinMessageLen = 2*kHeaderLen; // nameLen + typeName
    const static int kMaxMessageLen = 64*1024*1024;
};

} // namespace
#endif // __DSTH_PD_CODEC_H__
